
//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.



#ifndef __SYSTEM_INTERFACE__H_INCLUDED__
#define __SYSTEM_INTERFACE__H_INCLUDED__
#define NULL 0

//Most interfaces are here so this is one of the msot included file.

#ifdef _DEBUG
#define ASSERT(x) do { if(!x) {  abort(); } } while(0)
#else
#define ASSERT(x) do { if(!x) {  exit(1); } } while(0)
#endif

#include <vector>
#include "Managers\ManagerInterfaces.h"
namespace re
{
	namespace core
	{
		//----------------------------------------------------------------------------------------------------------------
		//~Engine's framework.
		//----------------------------------------------------------------------------------------------------------------
		class ManagerContainer;
		class ISystem;
		class IFramework
		{
		public:
			IFramework() {}

			virtual void LoadScene() = 0;
			virtual void SetupScene(bool minimal_rebuild) = 0;
			//System will be added automatically
			virtual bool LoadSystem(std::wstring& source, int priority) = 0;
			//if u want to load system which is linked static
			virtual void AddSystem(ISystem* system, int priority) = 0;
			virtual ManagerContainer* GetManagerContainer() = 0;
		};
		//----------------------------------------------------------------------------------------------------------------
		//System interface. Every system shoud get enough time to operate. Sheduler and task manager will take care
		//and call the following functions when needed, FROM DIFFERENCE THREAD.
		//----------------------------------------------------------------------------------------------------------------
		class ISystem;
		typedef std::vector<ISystem*> SystemList; // we actually need to change the systems once for a level. No need for std::list
		class ISystem
		{
		public:
			ISystem() {}

			virtual void Setup(ManagerContainer* managers) = 0;
			virtual void Update(TaskId id) = 0;
			virtual void ShutDown() = 0; // force shutdown

		};
		//function prototype that modules shoud implement so engine can instantiate the system they need.
		typedef ISystem* (*CreateSystemPtr)(void);

		//----------------------------------------------------------------------------------------------------------------
		//System copy. Logic system tells the engine how should it operate and when.
		//For example. Tell which scene to load, tell when some1 has finished,tell when shoud the engine quit..
		//(If u click X on the window, a message will be sent to logic and it will decide to exit or not!)
		//This is in case the game need to be saved.
		//----------------------------------------------------------------------------------------------------------------
		class ILogic : public ISystem
		{
		public:
			ILogic() {}

			virtual void StartUp(IFramework* framework) = 0;
			//virtual void Setup(ManagerContainer* managers, int system_id) = 0;
			//virtual void Update() = 0;
			//virtual void ShutDown() = 0; // force shut down
			virtual int GetPriority() = 0;
		};
	}
}

#endif